/*
 *  IO.c
 *  jscsh
 *
 *  Created by Jonathan Hohle on 1/9/08.
 *  Copyright 2008 hohle.net. All rights reserved.
 *
 */

#include "IO.h"
#include "util.h"

void IO_extendHost(JSContextRef context, JSObjectRef contextGlobalObject)
{
    JSStaticFunction staticFunctions[] = {
        {"read", IO_read, kJSPropertyAttributeNone},
        {0, 0, 0}
    };
    
    JSClassDefinition IO_definition = {
        0,
        kJSClassAttributeNone,
        
        "IO",
        NULL,
        
        NULL,
        staticFunctions,
        
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
    };

    JSClassRef IO = JSClassCreate(&IO_definition);
    JSObjectRef IOObject = JSObjectMake(context, IO, NULL);
    JSStringRef IOString = JSStringCreateWithUTF8CString("IO");
    JSObjectSetProperty(context,
                        contextGlobalObject,
                        IOString,
                        IOObject,
                        kJSPropertyAttributeNone,
                        NULL);
    JSClassRelease(IO);
    JSStringRelease(IOString);
}

JSValueRef IO_constructor(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    
}

//
// IO.read(filename [, length [, offset]])
//
JSValueRef IO_read(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    char* filename = NULL;
    long length = 0;
    long offset = 0;
    
    if (argumentCount == 0)
    {
        return JSValueMakeUndefined(context);
    }
    else if (argumentCount == 0 && argumentCount > 3)
    {
        *exception = JSValueMakeNumber(context, 1);
        return NULL;
    }
    
    filename = UTF8CStringFromJSValueRef(context, arguments[0]);
    char* fileContents = createStringWithContentsOfFile(filename);
    
    size_t fileLength = strlen(fileContents);
    
    if (argumentCount >= 2)
    {
        if (JSValueIsNumber(context, arguments[1]))
        {
            length = (long) JSValueToNumber(context, arguments[1], NULL);
        }
        else
        {
            *exception = JSValueMakeNumber(context, 1);
            return NULL;
        }
        
    }
    else
    {
        length = fileLength;
    }
    
    
    if (argumentCount == 3)
    {
        if (JSValueIsNumber(context, arguments[2]))
        {
            offset = (long) JSValueToNumber(context, arguments[2], NULL);
        }
        else
        {
            *exception = JSValueMakeNumber(context, 1);
            return NULL;
        }
    }
    
    
    if (offset > fileLength)
    {
        length = 0;
    }
    else if (offset + length > fileLength)
    {
        length = fileLength - offset;
    }
    
    char* returnUTF8String = malloc(length + 1);
    strlcpy(returnUTF8String, fileContents + offset, length + 1);
    JSValueRef returnValue = JSValueRefFromUTF8CString(context, returnUTF8String);
    
    free(fileContents);
    free(returnUTF8String);
    
    return returnValue;
}

JSValueRef IO_sysopen(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount == 0)
    {
        return JSValueMakeUndefined(context);
    }
}
